#ifndef TRANSITIONS_H
#define TRANSITIONS_H

#include "common_includes.h"

template<typename T>
class Transitions{
private:
public:
	array<array<T, NUM_STATES> , NUM_STATES> full;
	array<T, NUM_TRANSITIONS> compact;

	inline static State index_full_to_compact(const State i, const State j){
		State i_type = i / 12;
		State j_type = j / 12;
		State i_tone = i - (i_type * 12);
		State j_tone = j - (j_type * 12);
		int relative_tone;
		relative_tone = (j_type == 2) ? (0) : (j_tone - i_tone);
		relative_tone += (relative_tone >= 0) ? 0 : 12;

		return i_type * 25
				+ (i_type == 2 ? j_type : 12 * j_type + relative_tone);
	}

	inline void normalize_compact(){
		T c;

		c = 1 / accumulate(compact.cbegin(), compact.cbegin() + 25, T(0));
		transform(compact.cbegin(), compact.cbegin() + 25, compact.begin(),
				[=](T x){return x *= c;});

		c = 1 / accumulate(compact.cbegin() + 25, compact.cbegin() + 50, T(0));
		transform(compact.cbegin() + 25, compact.cbegin() + 50,
				compact.begin() + 25, [=](T x){return x *= c;});

		c = (compact[50] + compact[51]) * 12 + compact[52];
		c = 1 / c;
//		accumulate(compact.cbegin() + 50, compact.cbegin() + 53, T(0));
		transform(compact.cbegin() + 50, compact.cbegin() + 53,
				compact.begin() + 50, [=](T x){return x *= c;});
	}

	inline void compact_to_full(){
		for (unsigned i = 0; i < NUM_STATES; ++i){
			for (unsigned j = 0; j < NUM_STATES; ++j){
				full[i][j] = compact[index_full_to_compact(i, j)];
			}
		}
	}

//
//	inline Transitions(array<T, NUM_STATES>& transitions_compact){
//		set_transitions(transitions_compact);
//	}
};

#endif
